 # 腾讯证券内容获取

# 使用cookies自动登录 不用了
# 页面指定位置输入stock代码
# 新页面中获取最新新闻和公告
# 将获取内容和各stock文件中最新信息比对，以得到最新内容
# 将信息过滤，主要是关键字
# 将变化后的信息发送到邮箱
# 循环执行上述流程
# 设置脚本执行的时间点
# -公告新闻更新暂不考虑 后续观察公告中是否有新闻中没有的重要信息

# 需要修改的全局变量或配置：
# -先进行cookies的获取，而且可能需要不定时更新  不进行登录直接获取
# stock_url 登录地址
# stock_code_path stock代码路径 必需是主体主板 不含etf和
# stock_data_path 数据路径
# stock_templet_path 数据格式保存模板路径
# 新建templet.xlsx文件
# 写入文件的时候需求提前关闭掉

import json
import sys

from selenium import webdriver
from selenium.webdriver.common.by import By

import smtplib
import eyed3
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from pydub import AudioSegment
import email
import imaplib
import os
import shutil
import time
import traceback
import zipfile
from email.header import decode_header, Header
from email.utils import parseaddr
from pathlib import Path
import datetime
from selenium.webdriver.common.keys import Keys
import pandas as pd
import baostock as bs
import eventlet  # 导入eventlet这个模块



DEBUG = 1
PC_COM = 1  # 0-家庭 1-公司

Stock_url = "https://gu.qq.com/sh000001/zs"  # 检索地址

if PC_COM == 1:
    Stock_code_path = "D:\\video\\tool\\auto_tool\\a money\\code.xlsx"  # 股票代码读取路径
    Stock_data_path = "D:\\video\\tool\\auto_tool\\a money\\data"  # 数据保存路径 名字使用代码
    Stock_templet_path = "D:\\video\\tool\\auto_tool\\a money\\data\\templet.xlsx"  # 模板路径
else:
    Stock_code_path = "D:\\video\\tool\\auto_tool\\a money\\code.xlsx"  # 股票代码读取路径
    Stock_data_path = "D:\\video\\tool\\auto_tool\\a money\\data"  # 数据保存路径 名字使用代码
    Stock_templet_path = "D:\\video\\tool\\auto_tool\\a money\\data\\templet.xlsx"  # 模板路径

remote_server_url = 'imap.qq.com'
email_url = "3324564761@qq.com"  # 当前使用邮箱
password = "ioaeproulegrchff"
email_msg_to = "1984832368@qq.com"  # 发送邮箱
check_time = 10 # n 秒检测一次是否更新

pc_name = ["com", "fam"] # 运行 pc 环境

rewrite_print = print
def print(*arg):
   rewrite_print(*arg)
   output_dir = "log_file"
   if not os.path.exists(output_dir):
         os.makedirs(output_dir)
   log_name = 'log.txt' # 日志文件名称
   filename = os.path.join(output_dir, log_name)
   rewrite_print(*arg,file=open(filename,"a")) # 写入文件

def print_d(*arg): #仿真调试用
    if DEBUG == 1:
        print('------调试打印开始-----')
        print(*arg)
        print('------调试打印结束-----\r\n')


class email_data:
    def __init__(self):
        self.From = ""
        self.Subject = ""
        self.Date = ""
        self.filename = ""
        self.count = 0
        self.main_body = ""


    def printf(self, who):
        print(f'==========================================以上为调试，以下为{who}的真实有效数据========================================')
        print("From :% s ; Subject:% s ;  Date:% s ;  filename:% s ;  count:% s ;  main_body:% s ; " % (self.From, self.Subject, self.Date, self.filename, self.count, self.main_body))
        print(f'==========================================以上为{who}的真实有效数据==================================================')

    def reset(self):
        self.From = ""
        self.Subject = ""
        self.Date = ""
        self.filename = ""
        self.main_body = ""  #邮箱



class doc_function():  # 文件操作
    def save_data_txt(data):  # 添加数据到文件
        info_str = str(data)
        info_str += '\r\n'
        print(info_str)
        with open('flash_tool.log', 'a') as lead:
            lead.write(info_str)

    def set_data(data):  # 重写文件
        data_w = "data  " + data
        fi = open('data.txt', 'w', encoding='utf-8')
        fi.write(data_w)

    def mkdir(path):  # 新建文件夹
        folder = os.path.exists(path)

        if not folder:  # 判断是否存在文件夹如果不存在则创建为文件夹
            os.makedirs(path)  # makedirs 创建文件时如果路径不存在会创建这个路径
            print("---  new folder...  ---")
        else:
            print("folder is:", path)

    def copyfile(srcfile, dstpath):  # 复制文件
        if not os.path.isfile(srcfile):
            print("%s not exist!" % (srcfile))
        else:
            fpath, fname = os.path.split(srcfile)  # 分离文件名和路径
            if not os.path.exists(dstpath):
                os.makedirs(dstpath)  # 创建路径
            shutil.copy(srcfile, dstpath + fname)  # 复制文件

    def file_zip(start_file, zip_dir):  # 压缩文件
        # start_dir 要压缩的文件
        # zip_file 输出zip文件的路径
        fpath_start_dir, fname = os.path.split(start_file)  # 分离文件名和路径

        zip_file = zip_dir + '.zip'
        z = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED)
        print(z)
        for path, dirname, file_name in os.walk(fpath_start_dir):
            # print("文件夹根路径：", path)
            fpath = path.replace(fpath_start_dir, '')  # 去除根路径名称
            # print("--去除根路径：", fpath)
            fpath = fpath and fpath + os.sep  # 在原fpath加上\
            # print("****去除根路径+\ ：", fpath)

            for filename in file_name:  # 逐个循环读取文档名称
                if filename.find(fname) >= 0:
                    # print(filename)
                    z.write(os.path.join(path, filename), fpath + filename)  # 实现在输出路径的Zip压缩操作
        z.close()


    # def get_web():
        # if os.path.isfile("cfg.txt"):
        #     f = open(r"cfg.txt", "r", encoding="utf-8")
        #     data = f.read()
        #     reg = 'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'
        #     url = re.findall(reg, data)
        #     return url[-1]  # 假如地址在这一行的最后一个位置
        # else:
        #     print(" cfg.txt is not accessible, please creat!!!")
        #     sys.exit()

    def file_unzip_download(unzip_file):
        print(f"开始进行解压缩并下载···")

        zip_file = zipfile.ZipFile(unzip_file)
        fpath, fname = os.path.split(unzip_file)
        out_file = fpath + "\\unzip"
        if os.path.isdir(out_file):
            shutil.rmtree(out_file)
            os.mkdir(out_file)
        else:
            os.mkdir(out_file)
        for names in zip_file.namelist():
            zip_file.extract(names, out_file)
        zip_file.close()
        folder = Path(out_file.strip())
        result = list(folder.rglob(f'*{".hex"}*'))  # 只要hex文件
        print(result[0])  # 默认一个压缩包只有一个文件
        flash_file = str(result[0])
        # 进行文件的各种操作处理
        shutil.rmtree(out_file)

    def search_file(key_word, self_path=None):  # 查找的关键字 self_path是自定义路径
        if self_path != None:
            folder_str = self_path
        else:
            folder_str = os.path.join(os.getcwd(), qq_email_rx.Subject)  # 刘森 新世界

        folder = Path(folder_str.strip())
        # print(folder)
        if folder.exists():
            print("开始根据关键字查找文件···")
        else:
            print("未找到存放关键字对应文件的文件夹")
            return None

        result = list(folder.rglob(f'*{key_word}*'))
        if not result:
            print(f'在{folder} 下未找到关键字名称 {key_word} 的文件夹或文件')
            return None
        else:
            print(f'在{folder} 下找到关键字名称 {key_word} 的文件夹或文件{result}')
            return result

    def get_stock_code():  # 获取股票代码
        df = pd.read_excel(Stock_code_path, sheet_name=0, dtype={0:"string"})
        code_list = df["stock_code"].tolist()

        # 去掉中间的空项
        res = []
        for val in code_list:
            if str(val) != '<NA>':
                res.append(str(val))

        return res

    def get_str_row_column(words): #获取字符串中行数和列的最大字符数，返回两者的最大值
        row = words.count("\n") + 1

        # 存储所有的相同字符之间的距离
        length = []
        loc = 0
        last_loc = 0

        while words.find("\n", loc+1) != -1:
            loc = words.find("\n", loc+1)

            length.append(loc - last_loc)
            last_loc = loc

        length.append(len(words) - last_loc) # 获取最后一行长度
        # print(length)
        # print(f'最大长度：{max(length)}')
        column = max(length)
        # print(max(row, column))
        return max(row, column)

    def delete_files(file_path):
        if os.path.exists(file_path):
            shutil.rmtree(file_path)
            return True
        else:
            # file not found message
            print(f'要删除的文件夹{file_path}找不到')
            return False

    def cookie_creat(pc_name = pc_name[0]):  # 生成cook platform是投稿平台 pc_name是哪个pc
        web = webdriver.Chrome()
        web.get(Stock_url)

        web.delete_all_cookies()  # 先删除cookies
        time.sleep(60)  # 这个时间用于手动登录,扫码登录可以适当缩短这个等待时间
        dictcookies = web.get_cookies()  # 读取登录之后浏览器的cookies
        jsoncookies = json.dumps(dictcookies)  # 将字典数据转成json数据便于保存

        path_keyword = pc_name
        search_path = os.path.join(os.getcwd(), "cookies")
        doc_function.mkdir(search_path)
        save_name = search_path + "\\" + path_keyword + ".txt"
        print_d(save_name)

        with open(save_name, 'w') as f:  # 写进文本保存
            f.write(jsoncookies)
        print('cookie is ok')

    def cookie_use(pc_name = pc_name[0]):  # 使用cookie进行登录 返回web
        web = webdriver.Chrome()
        web.implicitly_wait(60)  # 隐性等待，最长等30秒


        web.get(Stock_url)

        path_keyword = pc_name
        search_path = os.path.join(os.getcwd(), "cookies")
        cook_name = search_path + "\\" + path_keyword + ".txt"

        if os.path.isfile(cook_name):
            f = open(cook_name, 'r')
            listcookie = json.loads(f.read())  # 读取文件中的cookies数据

            for cookie in listcookie:
                web.add_cookie(cookie)  # 将cookies数据添加到浏览器
            return web
            # web.refresh()  # 刷新网页
        else:
            # print("不存在此文件", cook_name)
            return web

        # input()  # 暂时暂停 否则一闪而过 后面有内容了再去掉

    def add_row_to_excel(data_row, excel_path): # 向excel中新加一行数据 data_row：行数据  excel_pat：路径
        print_d(data_row)
        df_all = pd.DataFrame(data=None)  # 创建空的 dataframe
        # 多数据做循环处理即可
        df = pd.read_excel(excel_path, header=0, sheet_name='Sheet1')  # 读入数据
        df_all = pd.concat([df_all, df], ignore_index=True)  # concat 合并有相同字段名的dataframe
        df = pd.DataFrame(data_row)
        df_all = pd.concat([df_all, df], ignore_index=True)

        data_list = df_all.drop_duplicates(keep='first')  # 避免字段名重复写入，一般会做去重处理
        df_all.to_excel(excel_path, index=False, encoding='utf-8')  # 写出数据

    def get_stock_codes(date=None): # 获取指定日期的A股代码列表  stock_codes = get_stock_codes()
        """
        获取指定日期的A股代码列表

        若参数date为空，则返回最近1个交易日的A股代码列表
        若参数date不为空，且为交易日，则返回date当日的A股代码列表
        若参数date不为空，但不为交易日，则打印提示非交易日信息，程序退出

        :param date: 日期
        :return: A股代码的列表
        """

        # 登录baostock
        bs.login()

        # 从BaoStock查询股票数据
        stock_df = bs.query_all_stock(date).get_data()

        # 如果获取数据长度为0，表示日期date非交易日
        if 0 == len(stock_df):

            # 如果设置了参数date，则打印信息提示date为非交易日
            if date is not None:
                print('当前选择日期为非交易日或尚无交易数据，请设置date为历史某交易日日期')
                sys.exit(0)

            # 未设置参数date，则向历史查找最近的交易日，当获取股票数据长度非0时，即找到最近交易日
            delta = 1
            while 0 == len(stock_df):
                stock_df = bs.query_all_stock(datetime.date.today() - datetime.timedelta(days=delta)).get_data()
                delta += 1

        # 注销登录
        bs.logout()

        # 筛选股票数据，上证和深证股票代码在sh.600000与sz.39900之间
        stock_df = stock_df[(stock_df['code'] >= 'sh.600000') & (stock_df['code'] < 'sz.399000')]

        # 返回股票列表
        return stock_df['code'].tolist()



class web_tx_parse:  # 腾讯的网页处理
    def __init__(self, pc):
        self.pc_name = pc   # pc_name[0] - com;   [1] - fam
        self.web = None

    def log_on(self):  # 登录
        print("登录中")
        web = doc_function.cookie_use(self.pc_name)
        web.refresh()  # 必需在这刷新，否则闪退
        self.web = web
        time.sleep(2)


    def data_signal(self, stock_code=None, key_word=None):  # 单个数据获取  stock_code:数字代码
        print(self.pc_name, "-信息获取中-", stock_code)

        # 获取信息并将信息保存
        # 输入代码号
        search_web = self.web.find_elements(By.XPATH, '//*[@id="root"]/div/div/div[2]/div[1]/form/div[1]/input')[0]
        search_web.send_keys(Keys.CONTROL, "a")
        search_web.send_keys(stock_code)
        time.sleep(2)
        search_web.send_keys(Keys.ENTER)
        time.sleep(1)

        news_xpath = '//*[@id="content_wrap"]/div[2]/div/div[4]/div/div[9]/div[1]/div/ul/li[1]/a'
        public_xpath = '//*[@id="content_wrap"]/div[2]/div/div[4]/div/div[9]/div[2]/div/ul/li[1]/a'
        news_data = self.web.find_elements(By.XPATH, news_xpath)[0]  # 新闻
        public_data = self.web.find_elements(By.XPATH, public_xpath)[0] #公告
        data_row = {"新闻": [news_data.get_attribute('title')], "新闻链接": [news_data.get_attribute('href')],"公告": [public_data.get_attribute('title')], "公告链接": [public_data.get_attribute('href')]}
        data_row_last = data_row
        # 进行信息保存
        stock_file_path = Stock_data_path + "\\" + stock_code + ".xlsx"
        if doc_function.search_file(stock_code, Stock_data_path) == None: # 这个文件没有则从模板新建 只保存一次
            shutil.copy(Stock_templet_path, stock_file_path)
            doc_function.add_row_to_excel(data_row, stock_file_path)  # 保存
        else: # 一直保存到最新消息
            df = pd.read_excel(stock_file_path, sheet_name=0, dtype={0: "string"})
            excel_row = df.iloc[-1].to_dict()

            # 新闻更新检索
            news_num = 1
            stock_update_list = []
            while data_row.get("新闻")[0] != excel_row.get("新闻") and news_num < 5: # 新闻发送变化 最大向前找5个
                last_str = "li[" + str(news_num)
                news_num = news_num + 1
                now_str = "li[" + str(news_num)
                news_xpath = news_xpath.replace(last_str, now_str)
                # print_d(news_xpath)

                news_data = self.web.find_elements(By.XPATH, news_xpath)[0]  # 新闻
                data_row = {"新闻": [news_data.get_attribute('title')], "新闻链接": [news_data.get_attribute('href')],"公告": [public_data.get_attribute('title')], "公告链接": [public_data.get_attribute('href')]}
                doc_function.add_row_to_excel(data_row, stock_file_path)  # 保存
                stock_update_list.append(data_row)

            # 邮箱发送
            if news_num == 1:
                print(stock_code, "------未发生新闻信息更新------")
            else:
                doc_function.add_row_to_excel(data_row_last, stock_file_path)  # 将最新的保存为最后一个
                stock_update_list.append(data_row)
                # 进行数据滤除和邮箱发送
                email_data = []
                for dict in stock_update_list:
                    if dict.get("新闻")[0].find(key_word) != -1:
                        email_data.append(dict.get("新闻"))
                        email_data.append(dict.get("新闻链接"))

                print_d(email_data)
                if email_data != []:
                    email_parse.send_email(email_url, password, email_msg_to, f'{stock_code} 新闻信息更新', " ".join('%s-' %a for a in email_data))
                    print(stock_code, "------发生新闻信息更新，已将更新信息发到邮箱------")
                else:
                    print(stock_code, "------发生新闻信息更新，但未发现关键字------")

            # 公告更新检索
            # 待补充

        # input()

    def data_all(self, key_word):  # 定时发布多个  key_word: 滤除信息的关键字
        # self.web.find_elements(By.XPATH, '/html/body/div[5]/div/div[3]')[0].click()  # 点除掉弹出的提示信息

        code_list = doc_function.get_stock_code()  # 获取股票代码
        # print(code_list)

        if code_list == None:
            return None

        eventlet.monkey_patch()  # 必须加这条代码
        for code in code_list:
            try:
                with eventlet.Timeout(20, False):  # 设置超时时间为20秒
                    try:
                        stock_get.data_signal(code, key_word)
                        time.sleep(1)
                        # 该语句正常执行
                    except Exception:
                        print(f'-------进行信息检查{code}出错-----\r\n')
            except Exception:
                print("----时间处理超时-----")



            # break  # 后续去掉


    def quit(self):  # 退出
        print(self.platform, "退出中")

class email_parse:  #邮件处理
    def __init__(self,remote_server_url,email_url,password):
        self.remote_server_url = remote_server_url
        self.email_url = email_url
        self.password = password

        self.subject_name = " "

    def decode_str(s):  # 解码字符串
        value, charset = decode_header(s)[0]
        if charset:
            value = value.decode(charset)
        return value

    def is_chinese(string): # 检查整个字符串是否包含中文
        for ch in string:
            if u'\u4e00' <= ch <= u'\u9fff':
                return True

        return False

    def set_charset(msg):  # 设置字符集
        charset = msg.get_charset()  # 获取字符集
        if charset is None:
            content_type = msg.get('Content-Type', '').lower()
            pos = content_type.find('charset=')
            if pos >= 0:
                charset = content_type[pos + 8:].strip()
        return charset

    def send_email(msg_from, passwd, msg_to, subject_rx, text_content, file_path=None): # 邮箱数据返回
      msg = MIMEMultipart()
      subject = subject_rx  # 主题
      text = MIMEText(text_content)
      msg.attach(text)

      if file_path:  # 最开始的函数参数我默认设置了None ，想添加附件，自行更改一下就好
          docFile = file_path
          docApart = MIMEApplication(open(docFile, 'rb').read())
          docApart.add_header('Content-Disposition', 'attachment', filename=docFile)
          msg.attach(docApart)
          print('发送附件:', file_path)
      msg['Subject'] = subject
      msg['From'] = msg_from
      msg['To'] = msg_to
      try:
          s = smtplib.SMTP_SSL("smtp.qq.com", 465)
          s.login(msg_from, passwd)
          s.sendmail(msg_from, msg_to, msg.as_string())
          print("邮件发送成功")
      except smtplib.SMTPException as e:
          print("邮件发送失败")
      finally:
          s.quit()

    def get_music_pic_url(key_word): #获取歌曲对应的图片链接 key_word是关键字 指定搜索引擎https://image.baidu.com/  返回地址
        print('进行数据爬取')
        from selenium import webdriver
        from selenium.webdriver.chrome.service import Service
        from selenium.webdriver.common.by import By

        url = 'https://image.baidu.com/'

        s = Service(r'C:\Users\addoi\AppData\Local\Google\Chrome\Application\chromedriver.exe')

        options = webdriver.ChromeOptions()
        # 设置为开发者模式，防止被各大网站识别出来使用了Selenium 没什么用
        options.add_argument("--disable-blink-features=AutomationControlled")
        options.add_experimental_option('excludeSwitches', ['enable-automation'])
        driver = webdriver.Chrome(service=s, options=options)

        driver.get(url)

        # 在搜索框自动输入内容
        driver.find_elements(By.XPATH, '//*[@id="kw"]')[0].send_keys(key_word)
        driver.find_elements(By.XPATH, '//*[@id="homeSearchForm"]/span[2]/input')[0].click()

        print(f'爬取关键字 {key_word} 的url地址是 {driver.current_url}')
        return driver.current_url


    def email_back(file_type): # 进行邮箱数据的返回 不同文件类型返回不同信息
        print('邮箱数据返回...')
        file_path = None
        if qq_email_tx.main_body == "":
            qq_email_tx.main_body = "没有匹配项，请检查主文格式和附件后重新发送，以下为示例\r\n 1、主题+mp3文件+时间戳（xxx-xxx）" \
                                    "\r\n2、图片\r\n3、图片序号（xx + 文字 + 换行\r\n4、ok/no + 子文件序号(xx) + 发布时间(月日时 xxxxxx) + 标题（2-20字）" \
                                    "\r\n5、合并文件（xx）-合并文件（xx）"

        if qq_email_rx.filename != "":  # 有附件
            # 1、收到mp3和时间戳 返回剪辑后的mp3和“请发图片”
            if qq_email_rx.filename[0].find(".mp3") != -1:  # 音频文件   or qq_email_rx.filename[0].find(".flac") != -1
                if qq_email_rx.main_body[:7].find(" ") != -1 and qq_email_rx.main_body[:3].isdigit() == True and qq_email_rx.main_body[4:7].isdigit() == True:  # 判断条件是有空格且全是数字 格式104 155 1分4秒到1分55秒
                    song_name = doc_function.search_file("mp3-")[0]
                    start_time = int(qq_email_rx.main_body[0]) * 60 + int(qq_email_rx.main_body[1:3])
                    end_time = int(qq_email_rx.main_body[4]) * 60 + int(qq_email_rx.main_body[5:7])

                    if song_name == None:
                        qq_email_tx.main_body = "1、未找到MP3文件" + "\r\n请发MP3文件！！！\r\n"
                    else:
                        mp3Info = eyed3.load(song_name)  # 检测音乐时长
                        mp3_time = mp3Info.info.time_secs
                        if start_time >= end_time or end_time > mp3_time:
                            qq_email_tx.main_body = f'1、时间不对, 应在{mp3_time}秒以内且前后不冲突 格式ex 123 145 '
                        else:  # 剪切 渐进渐出 重命名 保存（+cut） 返回
                            song = AudioSegment.from_mp3(song_name)  # 导入音乐
                            song = song[start_time * 1000:end_time * 1000]  # 提取片段 ms为单位
                            awesome = song.fade_in(5000).fade_out(3000)  # 渐进渐出

                            filepath, tempfilename = os.path.split(song_name)  # 剪切的音乐重命名
                            tempfilename = tempfilename.replace('mp3-', 'cut-')
                            song_cut = filepath + "\\" + tempfilename
                            awesome.export(song_cut)  # 导出音乐
                            file_path = song_cut
                            qq_email_tx.main_body = "1、收到mp3和时间戳，请查收剪辑后的mp3" + "-------请返回图片！！！"
                else:
                    qq_email_tx.main_body = "1、收到mp3,未收到时间戳" + "-------请发时间戳！！！"

            # 2、收到图片 保存路径为01234  返回”请发文字内容！！！“
            elif qq_email_rx.filename[0].find(".jpg") != -1 or qq_email_rx.filename[0].find(".bmp") != -1 or qq_email_rx.filename[0].find(".png") != -1:  # 图片文件
                qq_email_tx.main_body = "2、收到图片，序号为" + qq_email_tx.main_body + "-------请发文字（格式为：对应图片序号+文字+换行）！！！"

        else:  # 没有附件
            # 3、收到文字  上传成品到云 进行确认
            if qq_email_rx.main_body.find("\n") != -1 and qq_email_rx.main_body.find(" ") != -1 and \
                    email_parse.is_chinese(qq_email_rx.main_body[:5]) == True and qq_email_rx.main_body[0].isdigit() == True: # 判断条件是前5个字符有汉字、第一个字符是数字且有换行和空格

                # 查找是否含有此序号对应的照片
                digit_len = qq_email_rx.main_body.find(" ")
                check_file = "pic" + qq_email_rx.main_body[:digit_len] + "-"
                print_d(check_file)
                file_list = doc_function.search_file(check_file)
                if file_list[0] == None: # 未找到对应的照片
                    qq_email_tx.main_body = f'3、收到文字，未找到和文字序号对应的图片-------请重发文字（格式为：对应图片序号+空格+文字+换行）！！！'
                else:
                    # 将对应序号图片放到以文字序号为子文件夹的路径下
                    son_file_path = os.getcwd() + "\\" + qq_email_rx.Subject + "\\" + qq_email_rx.main_body[:digit_len]
                    print_d(son_file_path)
                    doc_function.mkdir(son_file_path)  # 创建文件夹
                    doc_function.copyfile(file_list[0], son_file_path + "\\") # 将图片复制到对应子文件夹
                    # 图文成片
                    song_name = doc_function.search_file("cut-")[0]
                    mp3Info = eyed3.load(song_name) # 检测音乐时长
                    mp3_time = mp3Info.info.time_secs
                    word_count = qq_email_rx.main_body.find("---原始邮件---") - 8 # 默认有正文则前有8个字节
                    word = qq_email_rx.main_body[(digit_len + 1):word_count]

                    # video_parse.pic_word_to_video(son_file_path, word, mp3_time)

                    qq_email_tx.main_body = f'3、收到文字，请在剪映云上进行成片确认或发布-------请回复"ok/no" + "子文件序号(xx)" + "发布时间(月日时 xxxxxx)" + "标题（2-20字）" ex： ok 02 010415 测试 \r\n------也可发送子文件夹序号1-2-3进行混剪发送！！！'

            # 4、先”ok“发布  ”no“删除  再子文件序号，然后时间是定时发布 后面是标题（发布的标题不能超过20个字） ex： ok 2 010415 测试 - 1月4日15点将子文件夹标题改为测试进行发布
            elif ((qq_email_rx.main_body[:5].find("ok") != -1 or qq_email_rx.main_body[:5].find("no") != -1)) and qq_email_rx.main_body[3].isdigit() == True:
                word_count = qq_email_rx.main_body.find("---原始邮件---") - 8
                if (word_count < 3 and qq_email_rx.main_body[:5].find("ok") != -1) or word_count > 32:  # 标题长度判断
                    qq_email_tx.main_body = f'4、收到回复，标题长度不对-------请回复"ok/no" + "子文件序号(xx)" + "发布时间(月日时 xxxxxx)" + "标题（2-20字）" ex： ok 02 010415 测试 ！！！'

                # 各项内容 ex： ok 02 010415 测试
                son_file = qq_email_rx.main_body[3:5]
                if qq_email_rx.main_body[3] == "0":
                    son_file = qq_email_rx.main_body[4] # 去除前面的无效0

                son_file_path = os.getcwd() + "\\" + qq_email_rx.Subject + "\\" + son_file
                if qq_email_rx.main_body[:5].find("ok") != -1: # 进行标题修改及定时发布
                    mp4_titel = qq_email_rx.main_body[13:(word_count-1)]
                    publish_time = qq_email_rx.main_body[6:12] # 加上年 分 秒
                    if os.path.exists(son_file_path):
                        video_parse.video_publish_time(son_file_path, mp4_titel, publish_time) # 修改标题 定时发布
                        qq_email_tx.main_body = f'4、收到回复，视频 {mp4_titel} 将于 {publish_time[0:2]}月{publish_time[2:4]}日{publish_time[4:6]}时 进行发布'
                    else:
                        qq_email_tx.main_body = f'4、要定时发布的文件夹 {son_file_path} 找不到'

                elif qq_email_rx.main_body[:5].find("no") != -1: # 删除son_file
                    if doc_function.delete_files(son_file_path) == True:
                        qq_email_tx.main_body = f'4、收到回复，文件夹已删除'
                    else:
                        qq_email_tx.main_body = f'4、要删除的文件夹 {son_file_path} 找不到'

            # 5、多个文件的合并发布 立即发布
            elif qq_email_rx.main_body[0:2].isdigit() == True and qq_email_rx.main_body[2] == '-' and qq_email_rx.main_body[3:5].isdigit() == True: # 格式是1-2-3
                son_num_len = qq_email_rx.main_body.find(" ")
                son = []
                loc = 0
                # 进行合并文件的查找
                word_count = qq_email_rx.main_body.find("---原始邮件---") - 8  # 默认有正文则前有8个字节
                while qq_email_rx.main_body.find("-", loc) != -1 and loc < (word_count-1):
                    loc = qq_email_rx.main_body.find("-", loc)
                    son.append(qq_email_rx.main_body[(loc-2):loc])
                    loc = loc + 2

                son.append(qq_email_rx.main_body[(word_count - 2):word_count])
                #进行合并发布 传入主题和son
                result = video_parse.merge_publish(qq_email_rx.Subject, son)
                if result == None:
                    qq_email_tx.main_body = f'5、收到回复，已将 {son} 合并发布！！！'
                else:
                    qq_email_tx.main_body = f'5、收到回复，子文件夹 {result} 找不到！！！'

        qq_email_tx.printf("发送")
        if DEBUG == 0:  # 调试的时候不返回数据
            email_parse.send_email(email_url, password, email_msg_to, qq_email_rx.Subject, qq_email_tx.main_body, file_path)


    def download_file(msg):  # 保存附件到指定路径
        fpath = os.getcwd()
        path_name = qq_email_rx.Subject  # 获取主题名字，作为文件夹名字

        out_file = fpath + "\\" + path_name
        print('文件保存路径是：', out_file)
        doc_function.mkdir(out_file)  #创建文件夹

        # 获取邮件主体信息
        attachment_files = []
        for part in msg.walk():
            file_name = part.get_filename()  # 获取附件名称类型
            contentType = part.get_content_type()  # 获取数据类型
            mycode = part.get_content_charset()  # 获取编码格式
            if file_name:
                h = Header(file_name)
                dh = decode_header(h)  # 对附件名称进行解码
                filename_download = dh[0][0]
                if dh[0][1]:
                    filename_download = email_parse.decode_str(str(filename_download, dh[0][1]))  # 将附件名称可读化
                attachment_files.append(filename_download)
                data = part.get_payload(decode=True)  # 下载附件
                with open(out_file + "\\" + filename_download, 'wb') as f:  # 在当前目录下创建文件，注意二进制文件需要用wb模式打开
                    f.write(data)  # 保存附件
                # 进行文件重命名，加上时间
                qq_email_rx.filename = attachment_files
                src = out_file + "\\" + filename_download
                if qq_email_rx.filename[0].find(".mp3") != -1:  # 音频文件
                    dst = out_file + "\\" + "mp3-" + qq_email_rx.Date + filename_download
                    time.sleep(2) # 为下载和重命名留时间
                elif qq_email_rx.filename[0].find(".jpg") != -1 or qq_email_rx.filename[0].find(".bmp") != -1 or qq_email_rx.filename[0].find(".png") != -1:  # 图片文件 重命名-在原类型数量基础上递增
                    pic_name = doc_function.search_file("pic")
                    if pic_name == None:
                        pic_num = 0
                    else:
                        pic_num = len(pic_name)
                    dst = out_file + "\\" + "pic" + str(pic_num) + "-" + qq_email_rx.Date + filename_download
                    qq_email_tx.main_body = qq_email_tx.main_body + str(pic_num) + "-"
                else: # 其它类型
                    dst = out_file + "\\" + qq_email_rx.Date + filename_download

                try:
                    os.rename(src, dst)
                except: # 文件重复异常处理
                    os.remove(dst)
                    os.rename(src, dst)

                print(f'附件 {filename_download} 已下载及重命名完成')

            elif contentType == 'text/plain':  # or contentType == 'text/html':
                # 输出正文 也可以写入文件
                data = part.get_payload(decode=True)
                content = data.decode(mycode)
                qq_email_rx.main_body = content
                # print('正文：', content)
        # print('附件文件名列表', qq_email_rx.filename)

    def get_email_title(msg):   # 获取发件人，主题和发送日期  返回主题名字
        for header in ['From', 'Subject', 'Date']:  # 遍历获取发件人，主题的相关信息
            value = msg.get(header, '')  # 获取邮件头的内容
            if value != '':
                if header == 'From':  # 解析字符串中的邮件地址
                    hdr, addr = parseaddr(value)
                    name = email_parse.decode_str(hdr)  # 解码字符串
                    value = '%s <%s>' % (name, addr)
                    qq_email_rx.From = name

                elif header == 'Subject': # 获取主题的信息，并解码
                    value = email_parse.decode_str(value)  # 解码字符串
                    if value.find("回复") != -1:  # 是回复信息
                        # 以回复后面的内容以此为文件夹
                        qq_email_rx.Subject = value[3:]
                        print(qq_email_rx.Subject)
                    else:
                        qq_email_rx.Subject = value

                elif header == 'Date':  # 获取日期的信息，并解码
                    value = email_parse.decode_str(value)  # 解码字符串
                    print(value)
                    time_format = datetime.datetime.strptime(value, '%a, %d %b %Y %H:%M:%S +%f')
                    qq_email_rx.Date = time_format.strftime("%Y-%m-%d %H-%M-%S-")
                    print(qq_email_rx.Date)


                print('%s: %s' % (header, value))

    def get_email_update(space): # 每隔space秒检测一次是否更新，进行状态返回，如果更新返回最新的邮件数量，否则返回0
        if DEBUG == 0:
            time.sleep(space)

        server = imaplib.IMAP4_SSL(remote_server_url, 993)
        server.login(email_url, password)
        server.select('INBOX')
        status, data = server.search(None, "ALL")
        if status != 'OK':
            raise Exception('read email error')
        emailids = data[0].split()
        mail_counts = len(emailids)
        current_time = datetime.datetime.now()
        current_time = current_time.strftime("%Y-%m-%d-%H:%M:%S")
        print(f'{str(current_time)}-邮件数量是 {mail_counts}')
        if mail_counts > qq_email_rx.count and qq_email_rx.count != 0 or DEBUG == 1:
            qq_email_rx.count = mail_counts
            return qq_email_rx.count
        else:
            qq_email_rx.count = mail_counts
            return 0

    def main_parse_Email(self):  # 处理email数据
        qq_email_rx.reset()
        qq_email_tx.reset()
        counts = email_parse.get_email_update(check_time)

        if counts == 0: #未更新
            return
        else:
            server = imaplib.IMAP4_SSL(self.remote_server_url, 993)
            server.login(self.email_url, self.password)
            server.select('INBOX')
            status, data = server.search(None, "ALL")
            if status != 'OK':
                raise Exception('read email error')
            emailids = data[0].split()
            mail_counts = counts

            status, edata = server.fetch(emailids[mail_counts-1], '(RFC822)')
            msg = email.message_from_bytes(edata[0][1])

            email_parse.get_email_title(msg) # 获取email title
            if qq_email_rx.From.find("叶绿素") == -1 and DEBUG == 0: # 不是指定邮箱的邮件
                print("不是指定邮箱发的文件")
                return
            elif qq_email_rx.Subject.find(" ") < 2  and DEBUG == 0: # 不是歌手+歌名的格式
                print("不是歌手+歌名的格式")
                return

            # 附件保存
            email_parse.download_file(msg)

            qq_email_rx.printf("接收")

            # 进行数据返回
            email_parse.email_back(qq_email_rx.filename)



if __name__ == "__main__":
    print("stock for money !!!!")
    check_num = 0
    stock_get = web_tx_parse(pc_name[0])
    stock_get.log_on()
    while 1:
        try:
            print('\r\n\r\n', datetime.datetime.now())
            check_num = check_num + 1
            print(f'进行第{check_num}次轮询检查\r\n')
            stock_get.data_all("中标")  # "中标"
            print(f'\r\n第{check_num}次轮询检查结束\r\n')
            time.sleep(60)
        except:
            print(f'第{check_num}次轮询检查出现错误\r\n')
            traceback.print_exc()
            continue








